package com.sixbro.aop.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * @Author: Mr.Lu
 * @Since: 2020/6/16 13:52
 */
@Aspect
@Component
public class WebValidateAspect {
    private final static Logger LOG = LoggerFactory.getLogger( WebValidateAspect.class );

    @Pointcut("execution(* com.sixbro.aop.api.*.*(..))")
    public void pointcut(){}

    /**
     * 环绕方法,可自定义目标方法执行的时机
     * @param joinPoint JoinPoint的子接口,添加了
     *                  Object proceed() throws Throwable 执行目标方法
     *                  Object proceed(Object[] var1) throws Throwable 传入的新的参数去执行目标方法
     *                  两个方法
     * @return 此方法需要返回值,返回值视为目标方法的返回值
     */
    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        Object result = null;

        try {
            //前置通知
            LOG.info("目标方法执行前... around");
            //执行目标方法
            //result = joinPoint.proeed();
            //用新的参数值执行目标方法
            result = joinPoint.proceed();
            //返回通知
            LOG.info("目标方法返回结果后...  around");
        } catch (Throwable e) {
            //异常通知
            LOG.info("执行目标方法异常后...  around");
            throw new RuntimeException(e);
        }
        //后置通知
        LOG.info("目标方法执行后...");

        return result;

    }

    /**
     * 前置方法,在目标方法执行前执行
     * @param joinPoint 封装了代理方法信息的对象,若用不到则可以忽略不写
     */
    @Before("pointcut()")
    public void before(JoinPoint joinPoint){
        LOG.info("目标方法名为:" + joinPoint.getSignature().getName());
        LOG.info("目标方法所属类的简单类名:" +        joinPoint.getSignature().getDeclaringType().getSimpleName());
        LOG.info("目标方法所属类的类名:" + joinPoint.getSignature().getDeclaringTypeName());
        /* System.out.println("目标方法声明类型:" + Modifier.toString(joinPoint.getSignature().getModifiers()));*/
        //获取传入目标方法的参数
        Object[] args = joinPoint.getArgs();
        for (int i = 0; i < args.length; i++) {
            LOG.info("第" + (i+1) + "个参数为:" + args[i]);
        }
        LOG.info("被代理的对象:" + joinPoint.getTarget());
        LOG.info("代理对象自己:" + joinPoint.getThis());
        LOG.info("before ******** before");
    }

    /**
     * 后置方法,在目标方法执行后执行
     */
    @After("pointcut()")
    public void after(){
        LOG.info("after ******** after");
    }
}
